package dxcTopic;

import java.util.Random;
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class ForkJoinPool_ArrSort{
    public static void main(String[] args)throws Exception{
        Random rand = new Random();
        //创建一个整形数组
        int[] data = new int[10];
        for(int i = 0;i < data.length;i ++){
            //为这个整形数组赋值
            data[i] = rand.nextInt(10);
        }
        System.out.print("创建数组"+Arrays.toString(data));
        //创建forkjoin线程池
        ForkJoinPool fjp = new ForkJoinPool();
        //创建线程任务对象
        MySortTask mst = new MySortTask(data,0,data.length);
        //提交任务对象
        fjp.invoke(mst);
        System.out.print("排序后数组"+Arrays.toString(data));

        //打印部分结果进行验证
        for(int i = 5;i < 9;i ++){
            System.out.println(data[i]);
        }


    }
}
//创建一个继承了RecursiveAction的类
class MySortTask extends RecursiveAction{
    int[] data;
    int start;
    int end;
    //设置阈值
    static final int threshold = 5;
    public MySortTask(int[]data,int start,int end){
        this.data = data;
        this.start = start;
        this.end = end;
    }
    public void compute(){
        //当数组长度小于阈值时候，直接计算
        if(end - start < threshold){
            Arrays.sort(data,start,end);
        }//当数组长度大于阈值时候，拆分计算
        else{
            int middle = (start+end)/2;
            //递归调用
            MySortTask mst1 = new MySortTask(data,start,middle);
            MySortTask mst2 = new MySortTask(data,middle,end);
            invokeAll(mst1,mst2);
            //合并数组
            merge(middle);
        }
    }

    //1.把两个数组中的数字依次进行比较，如果a[0]的值大于b[0]的值就将b[0]添加到总数组(小到大排序)，如果b[0]小于a[0]就将a[0]添加到总数组里。
    //2.重点是设置了x，y，这两个值分别代表两个数组中的下标，用于将数组中指定的数添加到总数组里面。
    //将两个排好序的小数组合并成为大数组
    public void merge(int middle){
        //将两个数组分别复制出来
        int[] a = Arrays.copyOfRange(data,start,middle);
        int[] b = Arrays.copyOfRange(data,middle,end);
        //设置两个标记符
        int x = 0;
        int y = 0;
        //将两个数组中的元素比较之后分别赋值到data数组中
        for(int i = start;i < end;i ++){
            //当a数组已经比较过最后一个值的时候，直接将b数组剩余的值赋值给data
            if(x == a.length ){
                data[i] = b[y++];
            }
           //当a数组已经比较过最后一个值的时候，直接将b数组剩余的值赋值给data
            else if(y == b.length ){
                data[i] = b[x++];
            }
                //将a[x]与b[y]依次比较，依次赋值
            else if(a[x] > b[y]){
                data[i] = b[y++];
            }
            else {
                data[i] = a[x++];
            }
            //data[i] = a[x++];
        }
    }
}
